package com.coocaa.ops.plus.dashboard.v1.verify;

import com.coocaa.ops.common.core.base.model.R;
import com.coocaa.ops.common.tool.exception.ExceptionUtil;
import com.coocaa.ops.plus.dashboard.v1.verify.util.VerifyImageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @author bijiahao
 * @date : 2023/8/11 17:48
 * @description
 */
@Slf4j
@RestController
public class VerifyController {

    /**
     * 获取资源图片路径
     */
    public List<String> queryFileList(String path) {

        //获取容器资源解析器
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        List<String> filelist = new ArrayList<String>();
        // 获取远程服务器IP和端口
        try {
            //获取所有匹配的文件
            Resource[] resources = resolver.getResources(path);
            for (Resource resource : resources) {
                filelist.add(resource.getFile().getPath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return filelist;
    }

    /**
     * 获取验证码
     * <p>
     * VerifyImageUtil 可考虑 加强验证难度，比如【小红书】 背景图生成时 多抠图一次随机模板。
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getImageVerify", produces = {"application/json;charset=UTF-8"})
    public Object getImageVerifyCode(HttpServletRequest request) {
        //bg图
        String IMG_PATH = "/image/bg/*.*";
        //模板图
        String TEMP_IMG_PATH = "/image/fg/*.*";

        // 读取背景图目录
        List<String> imgList = queryFileList(IMG_PATH);
        int randNum = new Random().nextInt(imgList.size());
        File targetFile = new File(imgList.get(randNum));
        // 读取模板目录
        List<String> tempimgList = queryFileList(TEMP_IMG_PATH);
        randNum = new Random().nextInt(tempimgList.size());
        File tempImgFile = new File(tempimgList.get(randNum));

        // 根据模板裁剪图片
        Map<String, Object> resultMap = null;
        try {
            resultMap = VerifyImageUtil.pictureTemplatesCut(tempImgFile, targetFile);
            int xWidth = (int) resultMap.get("xWidth");
            //缓存记录key，项目实现 redis 或者 requset seesion
            // Cached.set(key, xWidth);
            request.setAttribute("xWidth", xWidth);
            // 移除map的滑动距离，不返回给前端
            resultMap.remove("xWidth");
            //resultMap 包含 背景图片和浮动图片
            return R.ok().data(resultMap);

        } catch (Exception e) {
            log.error(ExceptionUtil.getErrorPrintLog("获取验证码失败", e));
            return R.error().msg("获取验证码失败");
        }
    }

    @RequestMapping(value = "/isVerify")
    public boolean isVerify(List<Integer> datas) {
        int sum = 0;
        for (Integer data : datas) {
            sum += data;
        }
        double avg = sum * 1.0 / datas.size();

        double sum2 = 0.0;
        for (Integer data : datas) {
            sum2 += Math.pow(data - avg, 2);
        }

        double stddev = sum2 / datas.size();
        return stddev != 0;
    }


    /**
     * 校验滑块拼图验证码
     *
     * @param moveLength 移动距离
     * @return BaseRestResult 返回类型
     * @Description: 生成图形验证码
     */
    @RequestMapping(value = "/verifyImageCode", produces = {"application/json;charset=UTF-8"})
    public R verifyImageCode(@RequestParam(value = "moveLength") String moveLength, HttpServletRequest request) {
        Double dMoveLength = Double.valueOf(moveLength);
        R res = null;
        try {
            //从redis或者reqest中获取 横向移动的距离
            int xWidth = (Integer) request.getAttribute("xWidth");
            if (xWidth < 1) {
                res = R.error().msg("验证过期，请重试");
            } else {
                // 设置允许的偏差值
                if (Math.abs((int) xWidth - dMoveLength) > 10) {
                    res = R.error().msg("验证不通过");
                } else {
                    res = R.ok().msg("验证通过");
                }
            }
        } catch (Exception e) {
            res = R.error().msg("验证失败，请重试");
        }
        return res;
    }
}
